package vip.meeet.thread.base;

import java.awt.print.Book;
import java.lang.ref.*;

/**
 * 强引用（Strong Reference）：即使进行了多次的GC回收，即使JVM真的已经不够用了，即使JVM最终不得已抛出了OOM错误，那么该引用继续抢占；
 * 软引用（Soft Reference）:当内存空间不足时，可以回收此内存空间。如果充足则不回收，可以用其完成缓存的一些处理操作开发。
 * 弱引用（Weak Reference）：不管内存是否紧张，只要一出现GC处理，则立即回收。
 * 幽灵引用（Phantom Reference）：
 */
public class ReferenceStart {

    public static void main(String[] args) {
        weakReference();
    }

    private static void weakReference(){
        WeakReference<String> weakReference = new WeakReference(new String("abc"));
        String result = weakReference.get();
        System.out.println(result);
//        System.out.println(weakReference.get());
        System.gc();
        System.out.println(weakReference.get());
    }

    private static void weakReference2(){
//        JVM触发gc时，就会回收该对象。与软引用不同的是，不管是否内存不足，弱引用都会被回收
        ReferenceQueue referenceQueue = new ReferenceQueue();
        WeakReference<String> weakReference = new WeakReference(new String("abc"), referenceQueue);
//        String book = weakReference.get();
//        System.out.println(book);
        System.out.println(weakReference.get());
        System.gc();
        System.out.println(weakReference.get());
//        Runtime.getRuntime().gc();
//        Reference reference = referenceQueue.poll();

    }

    private static void strongReference(){
        String strong = new String("Strong Reference");//强引用
    }

    private static void softReference(){
        //系统内存不足，导致软引用的对象被回收了，JVM会把这个软引用加入到与之相关联的ReferenceQueue中
        ReferenceQueue referenceQueue = new ReferenceQueue();
        SoftReference<Book> softReference = new SoftReference<>(new Book(), referenceQueue);
        Book book = softReference.get();
        Reference reference = referenceQueue.poll();
    }



    /**
     * 如果一个对象只有虚引用在引用它，垃圾回收器是可以在任意时候对其进行回收的，
     * 虚引用主要用来跟踪对象被垃圾回收器回收的活动，当被回收时，JVM会把这个弱引用加入到与之相关联的ReferenceQueue中。
     * 与软引用和弱引用不同的是，虚引用必须有一个与之关联的ReferenceQueue，通过phantomReference.get()得到的值为null
     *
     */
    private static void phantomReference(){
        ReferenceQueue referenceQueue = new ReferenceQueue();
        PhantomReference<Book> phantomReference = new PhantomReference<>(new Book(), referenceQueue);
        Book book = phantomReference.get(); //此值为null
        Reference reference = referenceQueue.poll();
    }
}
